#include "MyString.h"
#include <cstring>

#include <iostream>

// 无参构造
MyString::MyString() : size(0), capacity(15)
{
    s = new char[capacity];
}

// 带参构造
MyString::MyString(const char *str)
{
    size = strlen(str);
    capacity = size + 1 > 15 ? size + 1 : 15;
    s = new char[capacity];
    strcpy(s, str);
}

// 拷贝构造
MyString::MyString(const MyString &string)
{
    size = string.size;
    capacity = string.capacity;
    s = new char[capacity];
    strcpy(s, string.s);
}

// 析构
MyString::~MyString()
{
    delete[] s;
}

// +=运算符重载
MyString &MyString::operator+=(const MyString &string)
{
    size += string.size;
    if (size + 1 > capacity)
    {
        ReSize(size + 1);
    }
    strcat(this->s, string.s);
    return *this;
}

MyString &MyString::operator+=(const char &c)
{
    if (size + 1 > capacity)
        ReSize(capacity * 2);
    this->s[size++] = c;
    this->s[size] = '\0';
    return *this;
}

// + 运算符重载
MyString MyString::operator+(const MyString &string)
{
    MyString result = *this; // 拷贝构造
    result += string;
    return result;
}

// -= 运算符重载
MyString &MyString::operator-=(const MyString &string)
{
    char *dest = strstr(this->s, string.s);
    while (dest != nullptr)
    {
        char *back = dest + string.size;
        while (*back != '\0')
        {
            *dest++ = *back++;
        }
        *dest = '\0';
        this->size -= string.size;
        dest = strstr(this->s, string.s);
    }
    if (size + 1 < capacity / 2)
        ReSize(capacity / 2); // 优化下空间
    return *this;
}

// - 运算符重载
MyString MyString::operator-(const MyString &string)
{
    MyString result = *this;
    result -= string;
    return result;
}

// 返回找到元素
char &MyString::operator[](int index)
{
    return this->s[index];
}

bool MyString::operator==(const MyString &string)
{
    return strcmp(s, string.s) == 0;
}

bool MyString::operator!=(const MyString &string)
{
    return strcmp(s, string.s) != 0;
}

MyString::operator int()
{
    return atoi(this->s);
}

MyString::operator double()
{
    return atof(this->s);
}

MyStringArray MyString::split(const MyString &delim)
{
    MyString temp = *this; // 找一个临时值
    MyStringArray result;
    char *dest = strtok(temp.s, delim.s);
    while (dest != nullptr)
    {
        result += dest;
        dest = strtok(nullptr, delim.s);
    }
    return result;
}

void MyString::ReSize(int capacity)
{
    this->capacity = capacity;
    char *newS = new char[capacity];
    size = size > capacity - 1 ? capacity - 1 : size; // 往小缩或往大扩
    strncpy(newS, s, size);
    delete[] s;
    s = newS;
}

std::ostream &operator<<(std::ostream &os, const MyString &string)
{
    os << string.s;
    return os;
}

std::istream &operator>>(std::istream &is, MyString &string)
{
    char c = 0;
    while ((c = getchar()) != '\n' && c != ' ') // 读到\n为止
    {
        string += c;
    }
    return is;
}

MyString &MyString::operator=(const MyString &string) // 返回MyString 可以连续赋值
{
    delete[] s;
    size = string.size;
    capacity = string.capacity;
    s = new char[capacity];
    strcpy(s, string.s);
    return *this; // 返回自己
}

/*-----------------------------------------------------------------------------------------*/
// MyStringArray类
// 无参构造
MyStringArray::MyStringArray() : size(0), capacity(15)
{
    array = new MyString[capacity];
}

MyStringArray::MyStringArray(const MyString &string)
{
    size = 0;
    capacity = 5;
    if(size == capacity)
    {
        capacity *= 2;
    }
    array = new MyString[capacity];
    array[size++] = string;
}

// 拷贝构造
MyStringArray::MyStringArray(const MyStringArray &a)
{
    size = a.size;
    capacity = a.capacity;
    array = new MyString[capacity];
    for (int i = 0; i < size; i++)
    {
        array[i] = a.array[i];
    }
}

// 赋值运算符重载
MyStringArray &MyStringArray::operator=(const MyStringArray &a)
{
    delete[] array;
    size = a.size;
    capacity = a.capacity;
    array = new MyString[capacity];
    for (int i = 0; i < size; i++)
    {
        array[i] = a.array[i];
    }
    return *this;
}

// 析构函数
MyStringArray::~MyStringArray()
{
    delete[] array;
}

// += 运算符重载
MyStringArray &MyStringArray::operator+=(const MyString &str)
{
    if (size == capacity)
    {
        capacity *= 2;
        MyString *newS = new MyString[capacity];
        for (int i = 0; i < size; i++)
        {
            newS[i] = array[i];
        }
        delete[] array;
        array = newS;
    }
    array[size++] = str;
    return *this;
}

void MyStringArray::ArrayReSize(int capacity)
{
    this->capacity = capacity;
    MyString *newA = new MyString[capacity];
    size = size > capacity - 1 ? capacity - 1 : size;
    for (int i = 0; i < size; i++)
    {
        newA[i] = array[i];
    }
    delete[] array;
    array = newA;
}

MyStringArray &MyStringArray::operator+=(const MyStringArray &a)
{
    // int size1 = 0;
    // size1 = size + a.size;
    if (size + a.size > capacity)
    {
        ArrayReSize(size + a.size);
    }
    for (int i = 0; i < a.size; i++)
    {
        array[size++] = a.array[i];
    }
    // size = size + a.size;
    return *this;
}

MyStringArray MyStringArray::operator+(const MyString &str)
{
    // 存的是MyString类的多个对象
    MyStringArray result = *this;
    result += str;
    return result;
}

MyStringArray MyStringArray::operator+(const MyStringArray &a)
{
    MyStringArray result = *this;
    for (int i = 0; i < size; i++)
    {
        result += a.array[i];
    }
    return result;
}

MyStringArray &MyStringArray::operator-=(const MyString &str)
{
    if (size != 0)
    {
        int index = -1;
        for (int i = 0; i < size; i++)
        {
            if (array[i] == str)
            {
                index = i;
                break;
            }
        }
        if (index != -1)
        {
            for (int i = index; i < size; i++)
            {
                array[i] = array[i + 1];
            }
            size--;
        }
    }
    return *this;
}

MyStringArray &MyStringArray::operator-=(const MyStringArray &a)
{
    for (int i = 0; i < a.size; i++)
    {
        *this -= a.array[i];
    }
    if(size < capacity)
    {
        ArrayReSize(capacity / 2);
    }
    return *this;
}

bool MyStringArray::operator==(const MyString &str)
{
    for (int i = 0; i < size; i++)
    {
        if (array[i] == str)
        {
            return true;
        }
    }
    return false;
}

bool MyStringArray::operator==(const MyStringArray &a)
{
    if(size != a.size)
    {
        return false;
    }
    for(int i = 0;i < size;i++)
    {
        if(array[i] != a.array[i])
        {
            return false;
        }
    }
    return true;
}

MyString &MyStringArray::operator[](int index)
{
    return this->array[index];
}

MyStringArray MyStringArray::operator-(const MyString &str)
{
    MyStringArray result = *this;
    result -= str;
    return result;
}

MyStringArray MyStringArray::operator-(const MyStringArray &a)
{
    MyStringArray result = *this;
    for(int i = 0;i < a.size;i++)
    {
        result -= a.array[i];
    }
    return result;
}

std::ostream &operator<<(std::ostream &os, const MyStringArray &a)
{
    for (int i = 0; i < a.size; i++)
    {
        os << a.array[i] << std::endl;
    }
    return os;
}

std::istream &operator>>(std::istream &is, MyStringArray &a)
{
    MyString str;
    std::cin >> str;
    a.array[a.size++] = str;
    return is;
}
